import java.io.*;
import java.net.*;
import java.util.*;
import java.util.stream.Collectors;

public class EStoreServer {
    private ProductService productService;
    private UserService userService;
    private OrderService orderService;
    private CartService cartService;
    private ServerSocket serverSocket;
    private boolean running;

    public EStoreServer(int port) {
        try {
            this.productService = new ProductService();
            this.userService = new UserService();
            this.orderService = new OrderService();
            this.cartService = new CartService();
            this.serverSocket = new ServerSocket(port);
            this.running = true;

            System.out.println("服务器已启动，监听端口: " + port);
        } catch (IOException e) {
            System.err.println("服务器启动失败: " + e.getMessage());
        }
    }

    public void start() {
        while (running) {
            try {
                Socket clientSocket = serverSocket.accept();
                System.out.println("客户端连接: " + clientSocket.getInetAddress().getHostAddress());

                new Thread(() -> handleClient(clientSocket)).start();

            } catch (IOException e) {
                if (running) {
                    System.err.println("接受客户端连接失败: " + e.getMessage());
                }
            }
        }
    }

    private void handleClient(Socket clientSocket) {
        try (ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
             ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream())) {

            while (true) {
                String requestType = (String) ois.readObject();
                System.out.println("收到请求: " + requestType);

                Object requestData = ois.readObject();
                Object response = processRequest(requestType, requestData);

                oos.writeObject(response);
                oos.flush();

                if ("EXIT".equals(requestType)) {
                    break;
                }
            }

        } catch (EOFException e) {
            System.out.println("客户端断开连接");
        } catch (Exception e) {
            System.err.println("处理客户端请求时出错: " + e.getMessage());
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                System.err.println("关闭客户端连接时出错: " + e.getMessage());
            }
        }
    }

    private Object processRequest(String requestType, Object requestData) {
        try {
            switch (requestType) {
                case "USER_LOGIN":
                    Map<String, String> loginData = (Map<String, String>) requestData;
                    return userService.login(loginData.get("username"), loginData.get("password"));

                case "USER_REGISTER":
                    Map<String, String> registerData = (Map<String, String>) requestData;
                    return userService.register(
                            registerData.get("username"),
                            registerData.get("password"),
                            registerData.get("email")
                    );

                case "GET_ALL_PRODUCTS":
                    return productService.getAllProducts();

                case "ADD_PRODUCT":
                    Map<String, Object> productData = (Map<String, Object>) requestData;
                    Integer adminId = (Integer) productData.get("adminId");
                    if (userService.isAdmin(adminId)) {
                        Product product = (Product) productData.get("product");
                        return productService.addProduct(product);
                    }
                    return false;

                case "ADD_TO_CART":
                    Map<String, Object> cartData = (Map<String, Object>) requestData;
                    cartService.addToCart(
                            (Integer) cartData.get("userId"),
                            (Integer) cartData.get("productId"),
                            (Integer) cartData.get("quantity")
                    );
                    return true;

                case "GET_CART":
                    return cartService.getCart((Integer) requestData);

                case "CLEAR_CART":
                    cartService.clearCart((Integer) requestData);
                    return true;

                case "CREATE_ORDER":
                    return createOrderFromCart((Integer) requestData);

                case "GET_USER_ORDERS":
                    return orderService.getUserOrders((Integer) requestData);

                case "GET_ALL_ORDERS":
                    if (userService.isAdmin((Integer) requestData)) {
                        return orderService.getAllOrders();
                    }
                    return new ArrayList<Order>();

                case "EXIT":
                    return "BYE";

                default:
                    return "UNKNOWN_REQUEST";
            }
        } catch (Exception e) {
            return "ERROR: " + e.getMessage();
        }
    }

    private Object createOrderFromCart(Integer userId) {
        Cart cart = cartService.getCart(userId);
        if (cart == null || cart.getItems().isEmpty()) {
            return null;
        }

        List<OrderItem> orderItems = cart.getItems().entrySet().stream()
                .map(entry -> {
                    Product product = productService.getProductById(entry.getKey());
                    if (product != null) {
                        return new OrderItem(product.getId(), product.getName(), product.getPrice(), entry.getValue());
                    }
                    return null;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        if (orderItems.isEmpty()) {
            return null;
        }

        for (OrderItem item : orderItems) {
            if (!productService.updateStock(item.getProductId(), item.getQuantity())) {
                return null;
            }
        }

        Order order = orderService.createOrder(userId, orderItems);
        if (order != null) {
            cartService.clearCart(userId);
        }
        return order;
    }

    public static void main(String[] args) {
        EStoreServer server = new EStoreServer(8888);
        server.start();
    }
}